#!/usr/bin/env node

/**
 * FFmpeg和音频设备诊断工具
 * 用于诊断和解决FFmpeg SIGHUP错误和音频相关问题
 */

const { spawn, exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);

class FFmpegDiagnostic {
  async runDiagnostic() {
    console.log('🔍 开始FFmpeg和音频系统诊断...\n');

    try {
      await this.checkFFmpegInstallation();
      await this.checkAudioDevices();
      await this.checkPulseAudio();
      await this.testBasicFFmpegCommand();
      await this.checkPermissions();
      await this.testAudioCapture();
      
      console.log('\n✅ 诊断完成！');
    } catch (error) {
      console.error('\n❌ 诊断过程中出现错误:', error.message);
    }
  }

  async checkFFmpegInstallation() {
    console.log('📦 检查FFmpeg安装...');
    
    try {
      const { stdout } = await execAsync('ffmpeg -version');
      const versionLine = stdout.split('\n')[0];
      console.log(`✅ ${versionLine}`);
      
      // 检查关键编解码器支持
      if (stdout.includes('--enable-libpulse')) {
        console.log('✅ PulseAudio支持已启用');
      } else {
        console.log('⚠️  PulseAudio支持未启用');
      }
      
    } catch (error) {
      console.log('❌ FFmpeg未安装或不在PATH中');
      console.log('💡 安装方法: sudo apt install ffmpeg -y');
      throw error;
    }
  }

  async checkAudioDevices() {
    console.log('\n🎵 检查音频设备...');
    
    try {
      // 检查ALSA设备
      const { stdout: alsaDevices } = await execAsync('arecord -l || echo "no devices"');
      console.log('ALSA录音设备:');
      console.log(alsaDevices.trim() || '无设备');
      
      // 检查PulseAudio设备
      try {
        const { stdout: pulseDevices } = await execAsync('pactl list sources short');
        console.log('\nPulseAudio源设备:');
        console.log(pulseDevices.trim() || '无设备');
      } catch (e) {
        console.log('⚠️  无法获取PulseAudio设备列表');
      }
      
    } catch (error) {
      console.log('⚠️  无法检查音频设备:', error.message);
    }
  }

  async checkPulseAudio() {
    console.log('\n🔊 检查PulseAudio状态...');
    
    try {
      const { stdout } = await execAsync('pulseaudio --check -v');
      if (stdout.includes('running')) {
        console.log('✅ PulseAudio正在运行');
        
        // 获取默认源
        try {
          const { stdout: defaultSource } = await execAsync('pactl info | grep "Default Source"');
          console.log(`✅ ${defaultSource.trim()}`);
        } catch (e) {
          console.log('⚠️  无法获取默认音频源');
        }
        
      } else {
        console.log('❌ PulseAudio未运行');
      }
      
    } catch (error) {
      console.log('❌ PulseAudio检查失败:', error.message);
      console.log('💡 尝试启动: pulseaudio --start');
    }
  }

  async testBasicFFmpegCommand() {
    console.log('\n🧪 测试基本FFmpeg命令...');
    
    return new Promise((resolve) => {
      const testProcess = spawn('ffmpeg', [
        '-f', 'pulse',
        '-i', 'default',
        '-t', '1',
        '-f', 'null',
        '-'
      ]);

      let hasError = false;
      let errorOutput = '';

      testProcess.stderr.on('data', (data) => {
        errorOutput += data.toString();
      });

      testProcess.on('close', (code, signal) => {
        if (code === 0) {
          console.log('✅ 基本FFmpeg音频捕获测试成功');
        } else {
          console.log(`❌ FFmpeg测试失败 - code: ${code}, signal: ${signal}`);
          if (errorOutput) {
            console.log('错误输出:', errorOutput.slice(-200)); // 显示最后200字符
          }
        }
        resolve();
      });

      testProcess.on('error', (error) => {
        console.log('❌ FFmpeg进程启动失败:', error.message);
        resolve();
      });

      // 2秒超时
      setTimeout(() => {
        if (!testProcess.killed) {
          testProcess.kill('SIGTERM');
          console.log('⚠️  FFmpeg测试超时');
          resolve();
        }
      }, 2000);
    });
  }

  async checkPermissions() {
    console.log('\n🔐 检查权限和访问...');
    
    try {
      // 检查音频组权限
      const { stdout: groups } = await execAsync('groups');
      if (groups.includes('audio')) {
        console.log('✅ 用户在audio组中');
      } else {
        console.log('⚠️  用户不在audio组中');
        console.log('💡 添加到audio组: sudo usermod -a -G audio $USER');
      }
      
      // 检查设备访问权限
      try {
        const { stdout } = await execAsync('ls -la /dev/snd/');
        console.log('✅ 可以访问音频设备目录');
      } catch (e) {
        console.log('❌ 无法访问/dev/snd/目录');
      }
      
    } catch (error) {
      console.log('⚠️  权限检查失败:', error.message);
    }
  }

  async testAudioCapture() {
    console.log('\n🎤 测试音频捕获功能...');
    
    return new Promise((resolve) => {
      console.log('正在测试音频捕获（3秒）...');
      
      const captureProcess = spawn('ffmpeg', [
        '-f', 'pulse',
        '-i', 'default',
        '-ar', '16000',
        '-ac', '1',
        '-t', '3',
        '-f', 'wav',
        '/tmp/test_audio.wav'
      ]);

      let stderrOutput = '';

      captureProcess.stderr.on('data', (data) => {
        stderrOutput += data.toString();
      });

      captureProcess.on('close', (code, signal) => {
        if (code === 0) {
          console.log('✅ 音频捕获测试成功');
          
          // 检查文件是否创建
          exec('ls -la /tmp/test_audio.wav', (error, stdout) => {
            if (!error) {
              console.log('✅ 音频文件已生成:', stdout.trim());
              // 清理测试文件
              exec('rm -f /tmp/test_audio.wav');
            }
            resolve();
          });
          
        } else {
          console.log(`❌ 音频捕获测试失败 - code: ${code}, signal: ${signal}`);
          if (stderrOutput) {
            // 分析常见错误
            this.analyzeFFmpegErrors(stderrOutput);
          }
          resolve();
        }
      });

      captureProcess.on('error', (error) => {
        console.log('❌ 音频捕获进程启动失败:', error.message);
        resolve();
      });
    });
  }

  analyzeFFmpegErrors(errorOutput) {
    console.log('\n🔍 错误分析:');
    
    if (errorOutput.includes('Device or resource busy')) {
      console.log('❌ 设备忙碌 - 音频设备被其他程序占用');
      console.log('💡 解决方案: 关闭其他音频程序或重启PulseAudio');
    }
    
    if (errorOutput.includes('No such file or directory')) {
      console.log('❌ 设备不存在 - 找不到音频输入设备');
      console.log('💡 解决方案: 检查音频设备连接和驱动');
    }
    
    if (errorOutput.includes('Permission denied')) {
      console.log('❌ 权限拒绝 - 无法访问音频设备');
      console.log('💡 解决方案: 检查用户权限和音频组');
    }
    
    if (errorOutput.includes('Connection refused')) {
      console.log('❌ 连接被拒绝 - PulseAudio连接失败');
      console.log('💡 解决方案: 重启PulseAudio服务');
    }
    
    if (errorOutput.includes('Invalid data found')) {
      console.log('❌ 数据无效 - 音频格式或配置问题');
      console.log('💡 解决方案: 检查音频设备配置');
    }
  }

  async generateReport() {
    console.log('\n📄 生成诊断报告...');
    
    const report = {
      timestamp: new Date().toISOString(),
      system: {},
      ffmpeg: {},
      audio: {},
      recommendations: []
    };

    try {
      // 系统信息
      const { stdout: uname } = await execAsync('uname -a');
      report.system.kernel = uname.trim();
      
      const { stdout: lsb } = await execAsync('lsb_release -d 2>/dev/null || echo "Unknown"');
      report.system.distribution = lsb.trim();
      
      // FFmpeg信息
      try {
        const { stdout: ffmpegVersion } = await execAsync('ffmpeg -version 2>/dev/null | head -1');
        report.ffmpeg.version = ffmpegVersion.trim();
      } catch (e) {
        report.ffmpeg.version = 'Not installed';
        report.recommendations.push('安装FFmpeg: sudo apt install ffmpeg -y');
      }
      
      // 音频系统
      try {
        const { stdout: pulseStatus } = await execAsync('pulseaudio --check -v');
        report.audio.pulseaudio = pulseStatus.includes('running') ? 'Running' : 'Not running';
      } catch (e) {
        report.audio.pulseaudio = 'Not available';
        report.recommendations.push('启动PulseAudio: pulseaudio --start');
      }
      
      console.log('诊断报告:');
      console.log(JSON.stringify(report, null, 2));
      
    } catch (error) {
      console.error('生成报告时出错:', error.message);
    }
  }
}

// 如果直接运行此脚本
if (require.main === module) {
  const diagnostic = new FFmpegDiagnostic();
  diagnostic.runDiagnostic()
    .then(() => diagnostic.generateReport())
    .catch(console.error);
}

module.exports = FFmpegDiagnostic;